#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>


#define LISTEN_SZ 10

void *do_thread_client(void *arg) {

    // 线程处理函数
    ssize_t rbytes = 0, sbytes = 0;
    char buffer[1024] = {0};
    int cfd = *(int * ) arg;
    for(;;) {
        rbytes = recv(cfd, buffer, sizeof(buffer), 0);
        if (rbytes == -1) {
            perror("error fail to recv");
            pthread_exit(NULL);
        } else if (rbytes == 0) {
            printf("client quit\n");
            close(cfd);
            break;
        } else {
            // 客户端接收之后再将数据发回去
            sbytes = send(cfd, buffer, strlen(buffer), 0);
            if (sbytes == -1) {
                perror("error fail to send");
                close(cfd);
                pthread_exit(NULL);
            }

        }
    }
    close(cfd);
    pthread_exit(NULL);

}

int main(int argc, char const *argv[])
{
    int sfd, cfd;
    struct sockaddr_in svr_addr, cli_addr;
    char buffer[1024] = {0};
    int ret;
    pthread_t tid;

    sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd == -1) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }
    bzero(&svr_addr, sizeof(svr_addr));
    svr_addr.sin_family = AF_INET;
    svr_addr.sin_port = htons(atoi(argv[2]));
    svr_addr.sin_addr.s_addr = inet_addr(argv[1]);
    ret = bind(sfd, (struct sockaddr *)&svr_addr, sizeof(svr_addr));
    if (ret == -1) {
        perror("bind error");
        exit(EXIT_FAILURE);
    }
    ret = listen(sfd, LISTEN_SZ);
    if (ret == -1) {
        perror("listen error");
        exit(EXIT_FAILURE);
    }
   
    for(;;) {
        bzero(&cli_addr, sizeof(cli_addr));
        socklen_t len = sizeof(cli_addr);
        cfd = accept(sfd, (struct sockaddr *)&cli_addr, &len);
        if (cfd == -1) {
            perror("accept error");
            exit(EXIT_FAILURE);
        }
        printf("client ip: %s, port: %d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));

        // 创建线程
        ret = pthread_create(&tid, NULL, do_thread_client, (void *)&cfd);
        if (ret != 0) {
            perror("pthread_create error");
            exit(EXIT_FAILURE);
        }
        // 线程分离
        pthread_detach(tid); // 系统会在子线程结束后自动释放资源

    }

    
    


    return 0;
}
